Spring Boot的Java Config

Spring Boot不像Spring采用XML配置,而是使用Spring JavaConfig注解配置,配置方法更加简化。本文总结了Spring Boot的核心注解和常用注解。

1.核心注解@SpringBootApplication

@SpringBootApplication是Spring Boot的核心注解,通常用在项目的启动类上,申明让Spring Boot自动为程序进行必要的配置。其组合了以下三个注解:

  • @SpringBootConfiguration 组合了@Configuration注解,等同于Spring的XML配置文件功能,将注解类中的Bean装配到Spring容器中。
  • @EnableAutoConfiguration 打开自动配置的功能。会自动去maven中扫描项目依赖的每个starterjar包下的META-INF/spring.factories文件,扫描文件中key为EnableAutoConfiguration的所有配置类,将在配置类中配置的Bean加入到IOC容器中。
  • @ComponentScan 申明让Spring Boot扫描当前类(一般是启动类)所在包,找到所有组件类(Component、Controller、Service、Repository等),并将其装配到Spring IOC容器中,相当于加入到程序上下文(Spring中的applicationcontext.xml)。

@SpringBootApplication注解的源码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

...

}

2.常用注解

(1)配置导入功能

  • @Configuration 声明配置类,指出该类是Bean配置的信息源,相当于Spring的XML配置文件(中的<beans></beans>),一般注解在主类上
  • @Bean 相当于XML文件中的<bean></bean>注解方法而非类,意思是产生一个Bean,并交给Spring管理,一般和@Configuration 结合使用:
@Configuration
public class FusionOperationFactoryConfigure {
@Bean
public CommandLineRunner fusionOperationFactoryInitialization() {
return (args -> {
Reflections reflections = new Reflections("cn.ist.msplatform.channelservice.model.fusion");
for (Class clazz : reflections.getTypesAnnotatedWith(Fusion.class)) {
Fusion fusion = (Fusion) clazz.getAnnotation(Fusion.class);
FusionOperationFactory.register(fusion.operation(), clazz);
}
});
}
}
  • @Import 用来在当前配置类中导入其他配置类。在实际编码过程中,我们通常会将所需要的Bean分门别类地在不同的@Configuration类中进行声明配置,而不是写一个超级大的配置类来管理所有的SpringBean。有点类似于我们在Spring XML配置时写好几个文件比如application-context-dao.xml,application-context-service.xml之类的。使用@Import注解在不同的场景组合不同的配置类,该注解可以将其它@Configuration导入到当前的配置中。比如:
@Configuration
@Import({ SpringConfig1.class, SpringConfig2.class })
public class JavaConfigImport {

}
  • @ImportResource 与@Import做的事情相似,区别在于用来导入XML配置文件而非@Configuration配置类。比如:
@Configuration
@ImportResource("classptah: /application-context-*.xml")
public class JavaConfigImportResource {

}
  • @Autowired 自动导入依赖的beanbyType按类型装配方式,把配置好的Bean拿来用,完成对象自动装配的工作。当加上(required = false),就算找不到Bean也不报错。
  • @Resource(name = “name”, type = “type”) 与@Autowired干同样的事(适用于当同类型的Bean不止一个,需要借助name来指明要依赖的Bean的情况),没有括号内容的话默认byName按名称装配方式。Note:使用@Autowired+@Qualifier可以达到和使用@Resource一样的效果
@Configuration
@Slf4j
public class KafkaConfigure {
// 配置了三种同类型的Bean
@Bean
public KafkaProducer<String, String> kafkaProducer(@Value("${custom.kafka.url}") String url) {
// ...
}

@Bean
public KafkaConsumer<String, String> channelKafkaConsumer(@Value("${custom.kafka.url}") String url) {
// ...
}

@Bean
public KafkaConsumer<String, String> logKafkaConsumer(@Value("${custom.kafka.url}") String url) {
// ...
}
}
@Component
public class KafkaConsumerSingleton {
//使用@Autowired+@Qualifier实现按照类型+名称装配
@Autowired
@Qualifier("channelKafkaConsumer")
private KafkaConsumer<String, String> channelKafkaConsumer;
}
  • @Inject 等价于默认的@Autowired,没有required属性。

(2)业务层功能

  • @Component 泛指组件,当组件不好归类时,就用这个应付一下。
  • @Controller注解控制器类,在Spring项目中由控制器负责将用户发来的URL请求转发到对应的服务接口(service层)。一般在这个注解类中,通常方法需要配合注解@RequestMapping。
  • @RestController是@ResponseBody和@Controller的合集。
  • @Service 注解service层的组件。
  • @Repository 注解数据访问组件。
  • @RequestMapping 提供路由信息,负责URL到Controller中具体函数的映射。
  • @RequestBody 表示该方法的返回结果直接写入HTTP response body中。
  • @Value 注入application.properties或application.yml配置的属性的值。

(3)全局异常处理

  • @ControllerAdvice 内部包含了@Component注解,因此可以被扫描到,注解在上,统一处理异常。
  • @ExceptionHandler 注解在方法上面,表示遇到这个异常就执行这个方法,和@Controller配合使用:
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler()
@ResponseBody
ResponseEntity handle(ObjectNotFoundException e) {
return generateFailResponseEntity(ResultCode.OBJECT_NOT_FOUND, HttpStatus.NOT_FOUND, e.getMessage());
}


@ExceptionHandler()
@ResponseBody
ResponseEntity handle(ServiceException e) {
Result result = ResultUtil.failure(e.resultCode);
return new ResponseEntity(result, HttpStatus.OK);
}

@ExceptionHandler()
@ResponseBody
ResponseEntity handle(UnImplementedFeatureException e) {
return generateFailResponseEntity(ResultCode.UNIMPLEMENT_FEATURE, HttpStatus.OK, e.getMessage());
}

@ExceptionHandler()
@ResponseBody
ResponseEntity handle(RuntimeException e) {
log.error("", e);
Result result = ResultUtil.failure(e.getMessage(), ResultCode.RUN_TIME_EXCEPTION.getCode());
return new ResponseEntity(result, HttpStatus.OK);
}

private ResponseEntity generateFailResponseEntity(ResultCode resultCode, HttpStatus ok, String... message) {
String unformattedMessage = resultCode.getMessage();
int code = resultCode.getCode();
Result result = ResultUtil.failure(String.format(unformattedMessage, message), code);
return new ResponseEntity(result, ok);
}

}
文章作者: Moon Lou
文章链接: https://loumoon.github.io/2021/03/12/Spring Java Config/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Moon's Blog